package com.zyx.mpdemo.helpers.handler;


import cn.hutool.core.collection.CollUtil;
import com.zyx.mpdemo.common.constant.ResponseCode;
import com.zyx.mpdemo.common.exception.BusinessException;
import com.zyx.mpdemo.common.exception.code.ResultCode;
import com.zyx.mpdemo.common.resp.CommonResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Executable;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>全局异常捕获
 *
 * @author Yaxi.Zhang
 * @since 2022/10/1 08:27
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public CommonResponse<Void> invalidCommon(Exception ex) {
        log.error("全局异常捕获", ex);
        return new CommonResponse<>(ResponseCode.RESPONSE_CODE_500, "全局异常捕获：" + ex.getMessage(), null);
    }

    @ResponseBody
    @ExceptionHandler(value = BusinessException.class)
    public CommonResponse<Void> invalidBusiness(BusinessException ex) {
        log.error("业务异常捕获", ex);
        return new CommonResponse<>(ex.getCode(), ex.getMessage(), null);
    }


    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public CommonResponse<Void> methodArgumentNotValidException(MethodArgumentNotValidException ex) {
        log.error("全局异常捕获", ex);
        List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
        String errorStr = "";
        if (CollUtil.isNotEmpty(allErrors)) {
            errorStr = allErrors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(","));
        }
        Executable executable = ex.getParameter().getParameter().getDeclaringExecutable();
        if (Objects.nonNull(executable)) {
            String clazz = executable.getDeclaringClass().getName();
            String method = executable.getName();
            log.error("{}#{} 参数校验失败: [{}]", clazz, method, errorStr);
        }
        return new CommonResponse<>(ResultCode.FAILED.getCode(), "参数校验失败:" + errorStr, null);
    }

}
